const db = require("../models/index");
const utils = require("../utils");
const logger = require("../utils/_logger");

//整理统一返回格式
function resExtra(data, code = 0, message = '操作成功！') {
    if (code == -1) {
        data = null
    }
    return { data, code, message }
}

//查询列表条件处理
function queryConditions(conditions) {
    let queryCon = {
        raw: conditions?.raw ?? false,
        limit: parseInt(conditions.page_size) ?? 10, // 每页条数
        offset: conditions.page_size * (conditions.current_page - 1) || 0, // 当前页
        order: conditions.order ?? [['createdAt', 'desc']], //默认按插入时间进行升序
        attributes: conditions?.attributes ?? {},
        include: conditions?.include,
    };
    if (conditions.params) {
        queryCon.where = utils.tools.cleanObject(conditions.params);
    }
    if (!queryCon.limit) {
        delete queryCon.limit;
        delete queryCon.offset;
    };
    // 去除 deletedAt
    if (!conditions.attributes?.exclude?.includes('deletedAt')) {
        queryCon.attributes.exclude ??= [];
        queryCon.attributes.exclude.push('deletedAt');
    }
    return queryCon
}

const sqlOpt = {
    /**
     * 查询数据总条数
     * @param  {Object}   model       模型实例
     * @param  {Object}   conditions  条件集合
     * @param  {Function} cb          回调函数
     */
    count: (model, conditions, cb) => {
        if (!model) return cb && cb(resExtra('', -1, '当前网络不稳定，请稍后重试'));
        model.findAndCountAll(queryConditions(conditions)).then(data => {
            cb && cb(resExtra(data.count))
        }).catch(err => {
            logger.errLog(JSON.stringify(err))
            cb && cb(resExtra(err, -1, '查询条数失败'))
        })
    },

    /**
     * 查询数据列表 - 带分页
     * @param  {Object}   model       模型实例
     * @param  {Object}   conditions  条件集合
     * @param  {Function} cb          回调函数
     */
    list: (model, conditions, cb) => {
        // conditions.raw ??= true;
        if (!model) return cb && cb(resExtra('', -1, '当前网络不稳定，请稍后重试'));
        model.findAndCountAll(queryConditions(conditions)).then(countAll => {
            model.findAll(queryConditions(conditions)).then(data => {
                cb && cb(resExtra({
                    list: data,
                    total: countAll.count,
                    page_size: conditions.page_size || 1, // 每页显示条目个数
                    current_page: conditions.current_page, // 当前页数
                }))
            }).catch(err => {
                logger.errLog(err)
                cb && cb(resExtra(err, -1, '查询失败'))
            })
        }).catch(err => {
            logger.errLog(err)
            cb && cb(resExtra(err, -1, '查询失败'))
        })

    },

    /**
     * 查询数据列表 - 不带分页
     * @param  {Object}   model       模型实例
     * @param  {Object}   conditions  条件集合
     * @param  {Function} cb          回调函数
     */
    listAll: (model, conditions, cb) => {
        if (!model) return cb && cb(resExtra('', -1, '当前网络不稳定，请稍后重试'));
        model.findAll(queryConditions(conditions)).then(data => {
            cb && cb(resExtra(data))
        }).catch(err => {
            logger.errLog(JSON.stringify(err))
            cb && cb(resExtra(err, -1, '查询失败'))
        })
    },
    /**
     * 更具主键 获取一条数据
     * @param  {Object}   model       模型实例
     * @param  {Object}   conditions  条件集合
     * @param  {Function} cb          回调函数
     */
    findOne: (model, conditions, cb) => {
        if (!model) return cb && cb(resExtra('', -1, '当前网络不稳定，请稍后重试'));
        /* 根据主键查询一条数据 参数
        conditions:{
             id:'123'
         }*/
        if (!conditions.id) return cb && cb(resExtra('', -1, '查询条件为空！'));
        model.findByPk(conditions.id).then(data => {
            cb && cb(resExtra(data))
        }).catch(err => {
            logger.errLog(JSON.stringify(err))
            cb && cb(resExtra(err, -1, '查询失败'))
        })
    },

    /**
     * 创建数据
     * @param  {Object}   model       模型实例
     * @param  {Object}   obj         数据集合
     * @param  {Function} cb          回调函数
     */
    create: (model, obj, cb) => {
        model.create(obj, { raw: true }).then(data => {
            cb && cb(resExtra(data.toJSON(), 0, '创建成功！'))
        }).catch(err => {
            logger.errLog(JSON.stringify(err))
            cb && cb(resExtra(err, -1, '创建失败!'))
        })
    },

    /**
     * 更新数据
     * @param  {Object}   model       模型实例
     * @param  {Object}   obj         数据集合
     * @param  {Object}   key         更新条件
     * @param  {Function} cb          回调函数
     */
    update: (model, obj, key, cb) => {
        model.update(obj, { where: key }).then(data => {
            if (data[0]) {
                cb && cb(resExtra(data, 1, '更新成功！'))
            } else {
                cb && cb(resExtra('', -1, 'ID不存在！'))
            }
        }).catch(err => {
            logger.errLog(JSON.stringify(err))
            cb && cb(resExtra('', -1, '更新失败!'))
        })
    },

    /**
     * 删除某条数据
     * @param  {Object}   model       模型实例
     * @param  {Object}   key         删除条件
     * @param  {Function} cb          回调函数
     */
    delete: (model, key, cb) => {
        model.destroy({ where: key }).then(data => {
            if (data) {
                cb && cb(resExtra(data, 1, '删除成功！'))
            } else {
                cb && cb(resExtra('', -1, 'ID不存在！'))
            }
        }).catch(err => {
            logger.errLog(JSON.stringify(err))
            cb && cb(resExtra('', -1, '删除失败!'))
        })
    },

    /**
     * 删除整个表数据
     * @param  {Object}   model       模型实例
     * @param  {Function} cb          回调函数
     */
    deleteAll: (model, cb) => {
        model.destroy({ where: {}, truncate: false }).then(data => {
            if (!data) {
                cb && cb(resExtra(data, 0, '全部删除成功！'))
            } else {
                cb && cb(resExtra('', -1, '删除失败！'))
            }
        }).catch(err => {
            logger.errLog(JSON.stringify(err))
            cb && cb(resExtra('', -1, '删除失败!'))
        })
    },

    /**
     * 原始查询
     * @param  {String} sql           原始sql语句
     * @param  {Function} cb          回调函数
     */
    doQuery: (sql, cb) => {
        // sql = 'SELECT * FROM `tutorials`'
        db.sequelize.query(sql).then(data => {
            cb && cb(resExtra(data, 0, '查询成功！'))
        }).catch(err => {
            logger.errLog(JSON.stringify(err))
            cb && cb(resExtra('', -1, '查询失败!'))
        })
    },

}

module.exports = sqlOpt
